package com.cloud.service.generate;


import com.cloud.dao.UserDao;
import com.cloud.service.generate.auto.Action;
import com.cloud.service.generate.auto.QField;
import com.cloud.service.generate.auto.QFieldInfo;
import com.cloud.service.sys.AppService;
import com.cloud.util.SysUtil;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class FieldService {
    private static final Logger logger = Logger.getLogger(FieldService.class);

    @javax.annotation.Resource
    private UserDao userDao;

    public static List<QFieldInfo> getAllFieldInfo(Class clazz) {
        Field[] fields = clazz.getDeclaredFields();
        List<QFieldInfo> qFieldInfoAll = new ArrayList<>();
        for (Field field : fields) {
            QField qField = field.getAnnotation(QField.class);
            if (qField != null) {
                Map<String, String> enumMap = FieldService.getEnumValueMap();
                String enumValue = enumMap.get(field.getType().getSimpleName());
                QFieldInfo fieldInfo = new QFieldInfo();
                fieldInfo.fromQField(field, qField, enumValue);
                qFieldInfoAll.add(fieldInfo);
            }
        }
        return qFieldInfoAll;
    }

    public static Map<String, List<QFieldInfo>> getFieldMap(Class clazz) {
        Map<String, List<QFieldInfo>> qFieldMap = new HashMap<>();
        Field[] fields = clazz.getDeclaredFields();
        List<QFieldInfo> qFieldInfoAll = new ArrayList<>();
        for (Field field : fields) {
            QField qField = field.getAnnotation(QField.class);
            if (qField != null) {
                Action[] actions = qField.actions();
                QFieldInfo fieldInfo = new QFieldInfo();
                Map<String, String> enumMap = FieldService.getEnumValueMap();
                String enumValue = enumMap.get(field.getType().getSimpleName());
                fieldInfo.fromQField(field, qField, enumValue);
                for (Action action : actions) {
                    List<QFieldInfo> qFields = qFieldMap.get(action.name());
                    if (qFields == null) {
                        qFields = new ArrayList<>();
                        qFieldMap.put(action.name(), qFields);
                    }
                    qFields.add(fieldInfo);
                }
                qFieldInfoAll.add(fieldInfo);
            }
        }
        qFieldMap.put("all", qFieldInfoAll);
        List<QFieldInfo> editFields = qFieldMap.get(Action.edit.name());
        if (editFields == null) {
            editFields = new ArrayList<>();
        }
        return qFieldMap;
    }

    public static Map<String, String> getEnumValueMap() {
        Map<String, String> map = new HashMap<>();
        List<Class> classes = AppService.enums;
        for (Class model : classes) {
            //这里是获得枚举的遍历方法  即:枚举对象.values();一样      
            Method method = null;
            try {
                method = model.getMethod("values");
                //这里获取所有的枚举对象 method.invoke(null)也可写成method.invoke(null,null)
                Object inter[] = (Object[]) method.invoke(null);
                String desc = "";
                for (Object enumMessage : inter) {
                    Method name = model.getMethod("name");
                    Object nameVal = name.invoke(enumMessage, null);
                    Method getName = model.getMethod("getName");
                    Object getNameVal = getName.invoke(enumMessage, null);
                    desc += "'" + nameVal + "' : '" + getNameVal + "',";
                }
                if (SysUtil.isNotEmpty(desc)) {
                    map.put(model.getSimpleName(), "{" + desc.substring(0, desc.length() - 1) + "}");
                }
            } catch (Exception e) {
//                e.printStackTrace();
            }
        }
        return map;
    }
}
